#include <string.h>
#include "tst/test_frame.h"
#include "tst/bas/test_container_utility.h"
#include "bas/bas_hash_map.h"

int tst_basHashMapCreate(void)
{
    T_HashMap *ptHashMap = NULL;
    
    for (int i = 0; i < 10000; ++i)
    {
        TEST_ASSERT(ptHashMap = basHashMapCreate(_T(BUILDIN_STRING), _T(BUILDIN_STRING)));
        basHashMapDestroy(ptHashMap);
        TEST_ASSERT(ptHashMap = basHashMapCreate(_T(BUILDIN_STRING), _T(T_TestSimpleStruct)));
        basHashMapDestroy(ptHashMap);
    }

    return 0;
}

int tst_basHashMapInsert(void)
{
    T_HashMap *ptHashMap = NULL;
    char caBuff[100];

    for (int i = 0; i < 1; ++i)
    {
        TEST_ASSERT(ptHashMap = basHashMapCreate(_T(BUILDIN_STRING), _T(BUILDIN_STRING)));
        for (int j = 0; j < 100000; ++j)
        {
            snprintf(caBuff, sizeof(caBuff), "Hello%d", j);
            TEST_ASSERT(basHashMapInsert(ptHashMap, caBuff, caBuff) == 0);
        }
        for (int j = 0; j < 100000; ++j)
        {
            snprintf(caBuff, sizeof(caBuff), "Hello%d", j);
            TEST_ASSERT(strcmp(*(char **)basHashMapFind(ptHashMap, caBuff), caBuff) == 0);
        }
        basHashMapDestroy(ptHashMap);
    }
    
    return 0;
}

int tst_basHashMapErase(void)
{
    T_HashMap *ptHashMap = NULL;
    char caBuff[100];

    for (int i = 0; i < 1; ++i)
    {
        TEST_ASSERT(ptHashMap = basHashMapCreate(_T(BUILDIN_STRING), _T(BUILDIN_STRING)));
        for (int j = 0; j < 100000; ++j)
        {
            snprintf(caBuff, sizeof(caBuff), "Hello%d", j);
            TEST_ASSERT(basHashMapInsert(ptHashMap, caBuff, caBuff) == 0);
        }
        for (int j = 0; j < 50000; ++j)
        {
            snprintf(caBuff, sizeof(caBuff), "Hello%d", j);
            TEST_ASSERT(basHashMapErase(ptHashMap, caBuff) == 0);
        }
        for (int j = 50000; j < 100000; ++j)
        {
            snprintf(caBuff, sizeof(caBuff), "Hello%d", j);
            TEST_ASSERT(strcmp(*(char **)basHashMapFind(ptHashMap, caBuff), caBuff) == 0);
        }
        for (int j = 50000; j < 100000; ++j)
        {
            snprintf(caBuff, sizeof(caBuff), "Hello%d", j);
            TEST_ASSERT(basHashMapErase(ptHashMap, caBuff) == 0);
        }
        TEST_ASSERT(basHashMapEmpty(ptHashMap));
        basHashMapDestroy(ptHashMap);
    }

    return 0;
}

int tst_basHahsMapIterator(void)
{
    T_HashMap *ptHashMap = NULL;    

    for (int i = 0; i < 1; ++i)
    {
        TEST_ASSERT(ptHashMap = basHashMapCreate(_T(BUILDIN_STRING), _T(BUILDIN_STRING)));
        TEST_ASSERT(basHashMapInsert(ptHashMap, "Hello", "World") == 0);
        TEST_ASSERT(basHashMapInsert(ptHashMap, "Holy", "World") == 0);
        TEST_ASSERT(basHashMapInsert(ptHashMap, "Ice", "Fire") == 0);

        for (T_Iterator tIterator = basHashMapBegin(ptHashMap);
             !basIteratorEqual(tIterator, basHashMapEnd(ptHashMap));
             tIterator = basIteratorNext(tIterator))
        {
            printf("%s->%s\n", *(char **)BAS_ITER_GET_FIELD(tIterator, T_HashMapSlot, pvKey),
                   *(char **)BAS_ITER_GET_FIELD(tIterator, T_HashMapSlot, pvValue)); 
        }
        basHashMapDestroy(ptHashMap);
    }

    return 0;
}
